package cn.facetoken.homer;

import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import com.google.android.material.appbar.CollapsingToolbarLayout;

import org.apache.commons.lang3.StringUtils;

import java.util.Arrays;

import javax.annotation.Nonnull;

public class FaceRegistrationFragment extends Fragment implements View.OnClickListener, /*DialogInterface.OnClickListener,*/ PhotoTakingPrincipal {

    public FaceRegistrationFragment() {
        super();
    }

    private ImageView takenPhotoView;
    private EditText nameEditor;
    private Button saveButton;

    private PhotoTaker photoTaker;

    public static final int REQUEST_CODE_TAKE_PHOTO = 1;

    @Override
    public void onCreate(@Nullable final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        final CollapsingToolbarLayout appBarLayout = requireActivity().findViewById(R.id.toolbar_layout);
        if (appBarLayout != null) {
            appBarLayout.setTitle(getResources().getString(R.string.demonstration_face_registration_title));
        }
    }

    @Override
    public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable final ViewGroup container,
                             @Nullable final Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        final View rootView = inflater.inflate(R.layout.demonstration_face_registration, container, false);
        Log.i(getClass().getSimpleName(), String.format("Root view %s is inflated.", rootView.getClass().getName()));

        takenPhotoView = rootView.findViewById(R.id.taken_photo_view);
        takenPhotoView.setOnClickListener(this);
        if (null == photoTaker) {
            photoTaker = new PhotoTaker(this, requireActivity(), takenPhotoView);
        }

        nameEditor = rootView.findViewById(R.id.field_name);

        saveButton = rootView.findViewById(R.id.save_photo_button);
        saveButton.setOnClickListener(this);

        setupDynamicArea(rootView);

        return rootView;
    }

    private void setupDynamicArea(@Nonnull final View rootView) {
        @Nonnull final ViewGroup viewGroup = rootView.findViewById(R.id.dynamic_action_area);
        @Nonnull final String[] capabilities = new String[] { "landmarks5", "landmarks106" };
        @Nonnull final ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        for (String capability: capabilities) {
            @Nonnull final ImageView imageView = new ImageView(requireContext());
            imageView.setVisibility(View.GONE);
            viewGroup.addView(imageView, params);

            @Nonnull final Button button = new Button(requireContext());
            button.setText(String.format("%s %s", requireContext().getResources().getString(android.R.string.copy), capability));
            button.setTag(DynamicAction.TAG_DYNAMIC_ACTION);
            button.setTag(R.id.tag_key_action, DynamicAction.TAG_ACTION_COPY_TEXT);
            button.setTag(R.id.tag_key_name, capability);
            button.setOnClickListener(this);
            button.setPadding(16, 16,16, 16);

            viewGroup.addView(button, 240*3, 72*3);
        }
    }

    @Override
    public void onClick(@NonNull final View view) {
        if (view == takenPhotoView) {
            takePhoto();
        } else if (view == saveButton) {
            savePhoto();
        } else if (Boolean.TRUE==view.getTag()) {
            dynamicAct(view);
            Log.d(getClass().getSimpleName(), "onClick(): Dynamic Act.");
        }
    }

    private void dynamicAct(@NonNull final View view) {
        if (DynamicAction.TAG_ACTION_COPY_TEXT.equals(view.getTag(R.id.tag_key_action))) {
            final String name = (String)view.getTag(R.id.tag_key_name);
            final String text = (String)view.getTag(R.id.tag_key_data);
            getClipboardManager().setPrimaryClip(ClipData.newPlainText(name, text));
            Toast.makeText(requireContext(), R.string.copy_finished, Toast.LENGTH_LONG).show();
        }
    }

    @NonNull
    private ClipboardManager getClipboardManager() {
        return (ClipboardManager)requireContext().getSystemService(Context.CLIPBOARD_SERVICE);
    }

    public void startTakePhoto(@NonNull final Intent intent) {
        startActivityForResult(intent, REQUEST_CODE_TAKE_PHOTO);
    }

    @Override
    public void onActivityResult(final int requestCode, final int resultCode, @Nullable final Intent data) {
        Log.d(getClass().getSimpleName(), String.format("onActivityResult(): Request Code = %d, Result Code = %d, data = %s", requestCode, resultCode, data));
        switch (requestCode) {
            case REQUEST_CODE_TAKE_PHOTO:
                Log.i(getClass().getSimpleName(), "onActivityResult(): Request Code is TAKE PHOTO.");
                photoTaker.onPhotoTaken(resultCode, data);
                //Uri photoUri = photoTaker.onPhotoTaken(resultCode, data);
                //takenPhotoView.setTag(photoUri);
                break;
            case REQUEST_CODE_TAKE_PHOTO + 1:
            default:
                Log.e(getClass().getSimpleName(), "onActivityResult(): Request Code is strange.");
        }
    }

    private void takePhoto() {
        photoTaker.takePhoto();
    }

    private void savePhoto() {
        @NonNull final FaceSample faceSample = new FaceSample();
        faceSample.initialize();

        faceSample.name = nameEditor.getText().toString().trim();
        @NonNull final Uri sampleUri = (Uri) takenPhotoView.getTag(R.id.tag_key_photo_uri);

        if (null == sampleUri) {
            Log.e(getClass().getSimpleName(), "Failed to save photo, the URI of sample is null. Return!");
            return;
        }

        faceSample.sampleUri = sampleUri.toString().trim();
        //faceSample.angle = Configuration.ORIENTATION_LANDSCAPE == getResources().getConfiguration().orientation ? 0 : 90;

        if (StringUtils.isEmpty(faceSample.name)) {
            Toast.makeText(getContext(), getString(R.string.is_required, getString(R.string.field_name)), Toast.LENGTH_LONG).show();
            return;
        }

        if (StringUtils.isEmpty(faceSample.sampleUri)) {
            Toast.makeText(getContext(), getString(R.string.is_required, getString(R.string.field_photo)), Toast.LENGTH_LONG).show();
            return;
        }

        faceSample.extractEyeprintFeature(requireContext());
        faceSample.extractFaceFeature(requireContext());

        Log.d(getClass().getSimpleName(), String.format("savePhoto(): Insert Face Sample: Photo URI = %s, Name = %s.", faceSample.sampleUri, faceSample.name));
        Log.d(getClass().getSimpleName(), String.format("savePhoto():   Face Feature length = %d, content = %s.", faceSample.getFaceFeature().length, faceSample.faceFeature));
        Log.d(getClass().getSimpleName(), String.format("savePhoto():   Eyeprint Feature length = %d, content = %s.", faceSample.getEyeprintFeature().length, faceSample.eyeprintFeature));

        if (Arrays.equals(faceSample.getFaceFeature(), faceSample.getEyeprintFeature())) {
            Log.e(getClass().getSimpleName(), "Face feature & Eyeprint feature are identical.");
        }

        new Thread(
                () -> MainApplication.getMainDatabase().faceSampleDao().insert(faceSample)
        ).start();
        requireActivity().getSupportFragmentManager().beginTransaction()
                .replace(R.id.demonstration_container, new FaceRegistrationListFragment(), "FaceRegistrationList")
                .commit();
    }
}

